/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uk.ac.bath.machine.sane;

import uk.ac.bath.base.Evaluator;
import java.util.Arrays;
import java.util.Vector;
import uk.ac.bath.base.BasicEnvironment;
import uk.ac.bath.base.Cell;
import uk.ac.bath.base.Fitness;
import uk.ac.bath.gui.View;
import uk.ac.bath.util.MyRandom;

/**
 *
 * @author pjl
 */
public class SaneEnvironment extends BasicEnvironment  {

  //  ProgressViewer view;
    Gene genes[];
    private SaneContext c;
    private Gene[] net_pop;
//    int evaluations = 0;
    float best;
    int generation;
    int iTrial = 0;
    Evaluator evaluator;
   // private float fitness;
    boolean done=false;
    private int successfulCount;
    private long evalCount;

    public Evaluator getEvaluator() {
        return evaluator;
    }
    private int nSuccessTries=20;
    private Network currentNet;
   //  private boolean doZap;
    int neuronsPerNet;

    public SaneEnvironment(SaneContext c,  Evaluator eval) {
        super(eval);
        this.c = c;
    //    this.view = view;
        this.evaluator = eval;
        neuronsPerNet=c.nHidden+c.nOut;  // don't need inputs
        genes = new Gene[c.nPop];
        tweaks.addAll(eval.getTweaks());
        init();
    }


    protected synchronized void init() {

        successfulCount=0;
        done=false;
        currentNet=null;
        iTrial=0;
        generation=0;
        
//        evaluator.requestReset();
          
        best=0.0f;
        for (int i = 0; i < c.nPop; i++) {
            genes[i] = new Gene(c.bitsPerGene, true);
        }
        net_pop = new Gene[c.nHidden];
        this.best = 0.0f;
  //      doZap=false;
    }

//    public Network nextNetwork() {
//
//
//    }
    private Network createRandomNet() {
        /*find random subpopulation*/
        for (int j = 0; j < c.nHidden; ++j) {
            net_pop[j] = genes[MyRandom.nextInt(c.nPop)];
            net_pop[j].tests++;
        }

        Network net = Builder.build(net_pop, c);    /*form the network*/
        return net;
    }


    private void nextGeneration() {

        generation++;
        /*get average fitness level.  Multiply by 100 to get more resolution*/

        for (int i = 0; i < c.nPop; ++i) {
            if (genes[i].tests > 0) {
                genes[i].fitness = (float) ((genes[i].fitness * 100.0) / genes[i].tests);
            } else {
                genes[i].fitness = 0;
            }
        }


        Arrays.sort(genes, Gene.rev);

        for (int i = 0; i < c.numBreed; i++) {
            Gene a = genes[i];
            int nn = i;
            if (i == 0) {
                nn = c.numBreed;
            }
            Gene b = genes[MyRandom.nextInt(nn)];

            int point = MyRandom.nextInt(c.bitsPerGene + 1);

            Gene a1 = genes[c.nPop - 2 * i - 1];
            Gene b1 = genes[c.nPop - 2 * i - 2];

            for (int j = 0; j < c.bitsPerGene; j++) {
                if (j < point) {
                    a1.bits[j] = a.bits[j];
                    b1.bits[j] = b.bits[j];
                } else {
                    a1.bits[j] = b.bits[j];
                    b1.bits[j] = a.bits[j];
                }
            }
        }

        for (int i = c.numBreed; i < c.nOut; i++) {
            int point = MyRandom.nextInt(c.bitsPerGene);
            genes[i].bits[point] = !genes[i].bits[point];
        }

        for (Gene g : genes) {
            g.fitness = 0.0f;
            g.tests = 0;
        }

    }


    public View createSimulationView() {
        return evaluator.createView();
    }

    public Vector<Cell> getPopulation() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

  

    public void zap() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void nextEvaluation(Fitness fitness) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String status() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

 
}


